public class PushdownState extends State
{
	/*
	 * MEMBER VARIABLES
	 */
	
	// Stack is implemented as a String[].  Close enough!  
	private String[] _stack;
	private int _topOfStack = -1;
	// Transitions are stored in a String[].  Each transition takes up
	// four spots.  The first stores the letter to be read from the word, 
	// the second stores the state to go to, the third stores the letter
	// to be popped from the stack, and the fourth stores the letter to be
	// pushed onto the stack.  
	private String[] _transitions = new String[100];
	private int _transitionCount = 0;
	private String[] _stackAlphabet;
	public String _initialStack;
	public String[] getStack()
	{
		return this._stack;
	}
	
	
	/*
	 * CONSTRUCTORS
	 */
	
	public PushdownState(String name, String[] coords)
	{
		super(name, coords);
	}
	
	public PushdownState(String name)
	{
		super(name);
	}
	
	public PushdownState(String name, String[] coords, String[] transitions1, String[] stackAlphabet)
	{
		super(name, coords);
		this.parseTransitions(transitions1);
		this._stackAlphabet = stackAlphabet;
	}
	
	public PushdownState(PushdownState pushdown, String[] stack, int topOfStack)
	{
		super(pushdown.getName());
		this._accepting = pushdown._accepting;
		this._transitions = pushdown._transitions;
		this._transitionCount = pushdown._transitionCount;
		this._stack = stack;
		this._topOfStack = topOfStack;
	}
	
	
	
	/*
	 * CONCRETE METHODS
	 */

	// Transition data stored in two String[]'s for compatibility reasons
	@Override
	public void parseTransitions(String[] transitions)
	{
		for (int i = 0; i < transitions.length; i++)
		{
			if (transitions[i].split("\\+")[0].equals(this._name))
			{
				String[] transition = transitions[i].split("[");
				String[] transition1 = transition[0].split("\\+");
				String[] transition2 = transition1[1].split("=");
				String[] transition3 = transition[1].split("]");
				//String[] 1otherStuff = transitions[i].split("\\+")[1].split("=");
				if (transition3.length < 2)
				{
					if (transition3.length == 1)
					{
						transition3 = new String[] {transition3[0], ""};
					}
					else
					{
						transition3 = new String[] {"", ""};
					}
				}
				if (4 * this._transitionCount == this._transitions.length)
				{
					this.increaseTransitions();
				}
				this._transitions[4 * this._transitionCount] = transition2[0];
				this._transitions[4 * this._transitionCount + 1] = transition2[1];
				this._transitions[4 * this._transitionCount + 2] = transition3[0];
				this._transitions[4 * this._transitionCount + 3] = transition3[1];
				this._transitionCount++;
			}
		}
	}
	
	public boolean addTransition(PushdownState resultState, String letter, String pop, String push)
	{
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (this._transitions[4 * i + 1].equals(resultState.getName())
				&& this._transitions[4 * i].equals(letter)
				&& this._transitions[4 * i + 2].equals(pop)
				&& this._transitions[4 * i + 3].equals(push))
			{
				return false; // Transition already exists
			}
		}
		if (4 * this._transitionCount == this._transitions.length)
		{
			this.increaseTransitions();
		}
		this._transitions[4 * this._transitionCount] = resultState.getName();
		this._transitions[4 * this._transitionCount + 1] = letter;
		this._transitions[4 * this._transitionCount + 2] = pop;
		this._transitions[4 * this._transitionCount + 3] = push;
		this._transitionCount++;
		return true;
	}
	
	public boolean removeTransition(State resultState, String letter, String pop, String push)
	{
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (this._transitions[4 * i + 1].equals(resultState.getName())
				&& this._transitions[4 * i].equals(letter)
				&& this._transitions[4 * i + 2].equals(pop)
				&& this._transitions[4 * i + 3].equals(push))
			{
				for (int j = i; j < this._transitionCount - 1; j++)
				{
					this._transitions[4 * j] = this._transitions[4 * j + 4];
					this._transitions[4 * j + 1] = this._transitions[4 * j + 5];
					this._transitions[4 * j + 2] = this._transitions[4 * j + 6];
					this._transitions[4 * j + 3] = this._transitions[4 * j + 7];
				}
				this._transitions[4 * this._transitionCount] = null;
				this._transitions[4 * this._transitionCount + 1] = null;
				this._transitions[4 * this._transitionCount + 2] = null;
				this._transitions[4 * this._transitionCount + 3] = null;
				this._transitionCount--;
				return true;
			}
		}
		return false; // Transition did not exist
	}
	
	public void removeAllTransitions(State state)
	{
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (this._transitions[4 * i + 1].equals(state.getName()))
			{
				for (int j = i; j < this._transitionCount - 1; j++)
				{
					this._transitions[4 * j] = this._transitions[4 * j + 4];
					this._transitions[4 * j + 1] = this._transitions[4 * j + 5];
					this._transitions[4 * j + 2] = this._transitions[4 * j + 6];
					this._transitions[4 * j + 3] = this._transitions[4 * j + 7];
				}
				this._transitions[4 * this._transitionCount] = null;
				this._transitions[4 * this._transitionCount + 1] = null;
				this._transitions[4 * this._transitionCount + 2] = null;
				this._transitions[4 * this._transitionCount + 3] = null;
				this._transitionCount--;
			}
		}
	}
	
	public Object[] PAtrans(String letter)
	{
		Object[] results = new Object[0];
		int resultsIndex = 0;
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (this._transitions[4 * i].equals(letter)
				&& ((this._topOfStack > -1
					&& this._transitions[4 * i + 2].equals(this._stack[this._topOfStack]))
					|| this._transitions[4 * i + 2].equals("")))
			{
				String[] newStack = this._stack;
				int newTop = this._topOfStack;
				if (!this._transitions[4 * i + 2].equals(""))
				{
					newStack[newTop] = null; 
					newTop--;
				}
				if (!this._transitions[4 * i + 3].equals(""))
				{
					String[] temp = this._transitions[4 * i + 3].split("");
					for (int m = temp.length - 1; m > 0; m--)
					{
						if (newTop == newStack.length - 1)
						{
							Object[] newStack1 = increaseSizeBy3(newStack);
							newStack = new String[newStack1.length];
							for (int z = 0; z < newStack1.length; z++)
							{
								newStack[z] = (String)newStack1[z];
							}
						}
						newTop++;
						newStack[newTop] = temp[m];
					}
				}
				if (resultsIndex == results.length)
				{
					results = increaseSizeBy3(results);
				}
				results[resultsIndex] = this._transitions[4 * i + 1];
				results[resultsIndex + 1] = newStack;
				results[resultsIndex + 2] = newTop;
				resultsIndex += 3;
			}
		}
		return results;
	}
	
	public Object[] increaseSizeBy3(Object[] objectArray)
	{
		Object[] newArray = new Object[objectArray.length + 3];
		for (int i = 0; i < objectArray.length; i++)
		{
			newArray[i] = objectArray[i];
		}
		return newArray;
	}
	
	@Override
	public String getTransitionData()
	{
		String transitions = "";
		boolean anyYet = false;
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (anyYet)
			{
				transitions += ",";
			}
			transitions += this._name + "+";
			transitions += this._transitions[4 * i] + "=";
			transitions += this._transitions[4 * i + 1];
			anyYet = true;
		}
		return transitions;
	}
	
	public String getOtherTransitionData()
	{
		String transitions = "";
		boolean anyYet = false;
		for (int i = 0; i < this._transitionCount; i++)
		{
			if (anyYet)
			{
				transitions += ",";
			}
			transitions += this._transitions[4 * i + 2] + "+";
			transitions += this._transitions[4 * i + 3];
			anyYet = true;
		}
		return transitions;
	}
	
	
	
	/*
	 * GETTERS AND SETTERS
	 */
}